package com.lemon.boot.common.socket;

import com.lemon.boot.common.config.WebSocketConfiguration;
import com.lemon.boot.common.enums.SocketEnum;
import com.lemon.boot.common.utils.SocketUtil;
import com.lemon.boot.service.INoticeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author 李猛
 * @datetime 2024/5/27 15:52
 * @description 类对象
 */
@Slf4j
@Service
@ServerEndpoint(value = "/ws/notice/getNoRead", configurator = WebSocketConfiguration.class)
public class NoticeWebSocketService {
    private static INoticeService iNoticeService;

    @Autowired
    public void setNoticeService(INoticeService iNoticeService) {
        NoticeWebSocketService.iNoticeService = iNoticeService;
    }

    //存放所有在线的客户端
    private static final Map<Long, Session> clients = new ConcurrentHashMap<>();

    /**
     * 打开连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        Long userId = SocketUtil.getUserId(session);//获取用户ID
        clients.put(userId, session);
        session.getAsyncRemote().sendText(SocketEnum.CONNECT.getStatus());//异步返回
        log.info("有新连接加入，用户ID：{}，当前在线人数为：{}", userId, clients.size());
    }

    /**
     * 关闭连接
     *
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        Long userId = SocketUtil.getUserId(session);//获取用户ID
        clients.remove(userId);//移除用户
        SocketUtil.close(session);//关闭session
        log.info("有一连接关闭，用户ID：{}，当前在线人数为：{}", userId, clients.size());
    }

    /**
     * 接收消息
     *
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        Long userId = SocketUtil.getUserId(session);//获取用户ID
        log.info("服务端收到客户端{}的消息:{}", userId, message);
        if (SocketEnum.CONNECT.getHeartbeat().equals(message)) {
            session.getAsyncRemote().sendText(SocketEnum.CONNECT.getStatus());
        } else {
            send(userId);
        }
    }

    /**
     * 异常处理
     *
     * @param session
     * @param e
     */
    @OnError
    public void onError(Session session, Throwable e) {
        log.error("发生错误，用户ID：{}，当前在线人数为：{}，异常信息：{}", SocketUtil.getUserId(session), clients.size(), e.getMessage());
    }

    /**
     * 给指定用户推送消息
     *
     * @param userId
     */
    public void send(Long userId){
        Session session = clients.get(userId);
        if(Objects.nonNull(session) && session.isOpen()){
            long count = iNoticeService.getCountByUserId(userId, 0);
            session.getAsyncRemote().sendText(String.valueOf(count));
        }
    }

    /**
     * 给所有在线用户推送信息
     */
    public void send() {
        List<Long> userIdList = clients.entrySet().stream().filter(item -> item.getValue().isOpen()).map(Map.Entry::getKey).collect(Collectors.toList());
        Map<Long, Long> countByUserId = iNoticeService.getCountByUserId(userIdList);
        clients.forEach((key, value) -> value.getAsyncRemote().sendText(String.valueOf(countByUserId.get(key))));
    }
}
